/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.xuexiang.xui_lib.util;

import ohos.agp.colors.RgbColor;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentState;
import ohos.agp.components.element.Element;
import ohos.agp.components.element.PixelMapElement;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.components.element.StateElement;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.render.Texture;
import ohos.agp.utils.Color;
import ohos.agp.utils.RectFloat;
import ohos.agp.utils.TextAlignment;
import ohos.media.image.PixelMap;
import ohos.media.image.common.PixelFormat;
import ohos.media.image.common.Size;

import java.security.InvalidParameterException;

/**
 * DrawableUtils
 *
 * @since 2021-03-23
 */
public final class DrawableUtils {
    private static final float FACTOR = 0.8f;
    private static final int INT_2 = 2;

    private DrawableUtils() {
        throw new UnsupportedOperationException("u can't instantiate me...");
    }

    /**
     * 创建一张指定大小的纯色图片，支持圆角
     * <p>
     * Element类中有drawToCanvas(Canvas canvas) -->
     * Canvas(Texture texture) --> Texture(PixelMap pixelMap)，
     * 最终以image.setPixelMap(pixelMap);方式将pixelMap图添加到Image组件中。
     *
     * @param width 图片的宽度
     * @param height 图片的高度
     * @param cornerRadius 图片的圆角，不需要则传0
     * @param filledColor 图片的填充色 0xffff00ff
     * @return 指定大小的纯色图片
     */
    public static Element createDrawableWithSize(int width, int height, int cornerRadius, int filledColor) {
        PixelMap.InitializationOptions initializationOptions = new PixelMap.InitializationOptions();
        initializationOptions.size = new Size(width, height);
        initializationOptions.pixelFormat = PixelFormat.ARGB_8888;
        PixelMap pixelMap = PixelMap.create(initializationOptions);

        Texture texture = new Texture(pixelMap);
        Canvas canvas = new Canvas(texture);

        Element element = new PixelMapElement(pixelMap);
        element.drawToCanvas(canvas);

        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setColor(new Color(filledColor));
        paint.setStyle(Paint.Style.FILL_STYLE);
        canvas.drawRoundRect(new RectFloat(0, 0, width, height), cornerRadius, cornerRadius, paint);

        return element;
    }

    /**
     * 动态创建带上分隔线或下分隔线的Drawable。
     *
     * @param component 分割线颜色。
     * @param sepColor 分割线颜色。
     * @param bgColor Drawable 的背景色。
     * @param sepheight
     * @param isTop true 则分割线为上分割线，false 则为下分割线。
     * @noinspection checkstyle:JavadocMethod
     */
    public static void createItemSeparatorBg(Component component, int sepColor, int bgColor,
                                             int sepheight, boolean isTop) {
        int width = component.getWidth();
        int height = component.getHeight();

        PixelMap.InitializationOptions initializationOptions = new PixelMap.InitializationOptions();
        initializationOptions.size = new Size(width, height);
        initializationOptions.pixelFormat = PixelFormat.ARGB_8888;
        PixelMap pixelMap = PixelMap.create(initializationOptions);

        Texture texture = new Texture(pixelMap);
        Canvas canvas = new Canvas(texture);

        Element element = new PixelMapElement(pixelMap);
        element.drawToCanvas(canvas);

        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setColor(new Color(bgColor));
        paint.setStyle(Paint.Style.FILL_STYLE);
        canvas.drawRoundRect(new RectFloat(0, 0, width, height), 0, 0, paint);

        paint.setColor(new Color(sepColor));
        if (isTop) {
            canvas.drawRoundRect(new RectFloat(0, 0, width, sepheight), 0, 0, paint);
        } else {
            canvas.drawRoundRect(new RectFloat(0, height - sepheight, width, height), 0, 0, paint);
        }
        component.setBackground(element);
    }

    /**
     * 创建一张指定大小的圆形图片，并附带文字
     *
     * @param size 图片的宽度
     * @param filledColor 图片的填充色
     * @param text 文字
     * @param textSize 文字大小(px)
     * @param textColor 文字颜色
     * @return 指定大小的纯色图片
     * @throws InvalidParameterException
     */
    public static Element createCircleDrawableWithText(int size, int filledColor,
                                                       String text, int textSize, int textColor) {
        if (size <= 0) {
            throw new InvalidParameterException("bitmap size must be > 0!");
        }
        if (textSize <= 0) {
            throw new InvalidParameterException("text size must be > 0!");
        }
        PixelMap.InitializationOptions initializationOptions = new PixelMap.InitializationOptions();
        initializationOptions.size = new Size(size, size);
        initializationOptions.pixelFormat = PixelFormat.ARGB_8888;
        PixelMap pixelMap = PixelMap.create(initializationOptions);

        Texture texture = new Texture(pixelMap);
        Canvas canvas = new Canvas(texture);

        Element element = new PixelMapElement(pixelMap);
        element.drawToCanvas(canvas);

        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setColor(new Color(filledColor));
        paint.setStyle(Paint.Style.FILL_STYLE);
        int radius = size / INT_2;
        canvas.drawCircle(radius, radius, radius, paint); // 画圆

        paint.setColor(new Color(textColor)); // 画文字
        paint.setTextSize(textSize);
        paint.setTextAlign(TextAlignment.CENTER);
        float baseline = radius + getBaselineDistance(paint);
        canvas.drawText(paint, text, radius, baseline);
        return element;
    }

    /**
     * 获取画笔的基线距离
     *
     * @param paint 画笔
     * @return 基线距离
     */
    private static float getBaselineDistance(Paint paint) {
        Paint.FontMetrics fontMetrics = paint.getFontMetrics();
        return (fontMetrics.bottom - fontMetrics.top) / INT_2 - fontMetrics.bottom;
    }

    /**
     * 实体 按下的颜色加深
     *
     * @param cornerRadius 圆角半径
     * @param normalColor 正常的颜色
     * @return 状态选择器
     */

    public static Element getDrawable(int cornerRadius, int normalColor) {
        return getStateListDrawable(cornerRadius, ColorUtils.darker(normalColor, FACTOR), normalColor);
    }

    /**
     * 背景选择器
     *
     * @param cornerRadius 圆角半径
     * @param pressedColor 按下状态的色值
     * @param normalColor 正常状态的色值
     * @return 状态选择器
     */
    public static Element getStateListDrawable(int cornerRadius, int pressedColor, int normalColor) {
        ShapeElement normalElement = new ShapeElement();
        normalElement.setCornerRadius(cornerRadius);
        normalElement.setRgbColor(new RgbColor(normalColor));

        ShapeElement selectedElement = new ShapeElement();
        selectedElement.setCornerRadius(cornerRadius);
        selectedElement.setRgbColor(new RgbColor(pressedColor));

        StateElement background = new StateElement();
        background.addState(new int[]{ComponentState.COMPONENT_STATE_PRESSED}, selectedElement);
        background.addState(new int[]{ComponentState.COMPONENT_STATE_EMPTY}, normalElement);
        return background;
    }
}
